package com.sondertara.joya.core.model;


import com.sondertara.common.text.StringUtils;
import com.sondertara.common.collection.BiMap;
import com.sondertara.common.collection.LinkedCaseInsensitiveMap;
import com.sondertara.joya.core.jdbc.support.meta.TableDescription;
import lombok.Getter;
import lombok.Setter;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * the table data entity
 *
 * @author huangxiaohu
 */

public class EntityTableMetaDefinition implements Serializable {

    @Getter
    @Setter
    private TableDescription tableDescription;


    private Class<?> entityClass;

    @Setter
    @Nullable
    private String schemaName;


    /**
     * the table name
     */
    @Getter
    @Setter
    @NonNull
    private String tableName;
    /**
     * primary key name if exist
     */
    @Setter
    @Getter
    private String primaryKey;
    /**
     * the type of primary key
     */
    @Setter
    @Getter
    private Class<?> primaryKeyType;
    /**
     * the relation of column and the field
     * <p>
     * key is table column name ,value is the field name
     */
    @Getter
    private LinkedCaseInsensitiveMap<String> columnPropertyRelation;
    /**
     * the column class type
     * key is table column name
     */
    @Getter
    private LinkedCaseInsensitiveMap<Field> columnFieldRelation;
    private BiMap<String, String> relationBiMap;

    public BiMap<String, String> columnPropertyRelationBiMap() {
        return relationBiMap;
    }

    public void setColumnPropertyRelation(LinkedCaseInsensitiveMap<String> relation) {
        this.columnPropertyRelation = relation;
        this.relationBiMap = new BiMap<>(this.columnPropertyRelation);
    }

    public List<String> getColumnNames() {
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, String> entry : this.getColumnPropertyRelation().entrySet()) {
            list.add(entry.getKey());
        }
        return list;
    }

    public List<String> getFieldNames() {
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, String> entry : this.getColumnPropertyRelation().entrySet()) {
            list.add(entry.getValue());
        }
        return list;
    }


    public void setColumns(LinkedCaseInsensitiveMap<Field> columns) {
        this.columnFieldRelation = columns;
    }

    public Class<?> getEntityClass() {
        return entityClass;
    }

    public void setEntityClass(Class<?> entityClass) {
        this.entityClass = entityClass;
    }

    public String getSchemaName() {
        if (StringUtils.isBlank(schemaName)) {
            return null;
        }
        return schemaName;
    }

}
